管理文件 | 您所在的位置:网站首页 › django DEFAULT_FILE_STORAGE › 管理文件 |
管理文件¶
这个文档描述 Django 文件访问用于文件的 API,例如用户上传的文件。较底层的API足够通用,你可以为其他目的来使用它们。如果你想处理 "static files" (JS, CSS, etc.),可以查看 如何管理静态文件(如图片、JavaScript、CSS) 。 默认情况下,Django 使用 MEDIA_ROOT 和 MEDIA_URL 设置本地存储。下面的例子假设你在使用这些默认设置。 不过,Django 提供编写自定义 file storage systems 的方法,允许你完全自定义 Django 存储文件的位置和方式。这篇文档的后半部分描述了存储系统的工作方式。 在模型中使用文件¶当你使用 FileField 或 ImageField 时,Django 提供了一组处理文件的API。 考虑下面的模型,使用 ImageField 来存储照片: from django.db import models class Car(models.Model): name = models.CharField(max_length=255) price = models.DecimalField(max_digits=5, decimal_places=2) photo = models.ImageField(upload_to="cars") specs = models.FileField(upload_to="specs")Any Car instance will have a photo attribute that you can use to get at the details of the attached photo: >>> car = Car.objects.get(name="57 Chevy") >>> car.photo >>> car.photo.name 'cars/chevy.jpg' >>> car.photo.path '/media/cars/chevy.jpg' >>> car.photo.url 'http://media.example.com/cars/chevy.jpg'car.photo 是一个 File 对象,这意味着它拥有下面所描述的所有方法和属性。 备注 文件在数据库中作为保存模型的一部分,因此在模型被保存之前,不能依赖磁盘上使用的实际文件名。 For example, you can change the file name by setting the file's name to a path relative to the file storage's location (MEDIA_ROOT if you are using the default FileSystemStorage): >>> import os >>> from django.conf import settings >>> initial_path = car.photo.path >>> car.photo.name = "cars/chevy_ii.jpg" >>> new_path = settings.MEDIA_ROOT + car.photo.name >>> # Move the file on the filesystem >>> os.rename(initial_path, new_path) >>> car.save() >>> car.photo.path '/media/cars/chevy_ii.jpg' >>> car.photo.path == new_path TrueTo save an existing file on disk to a FileField: >>> from pathlib import Path >>> from django.core.files import File >>> path = Path("/some/external/specs.pdf") >>> car = Car.objects.get(name="57 Chevy") >>> with path.open(mode="rb") as f: ... car.specs = File(f, name=path.name) ... car.save() ...备注 While ImageField non-image data attributes, such as height, width, and size are available on the instance, the underlying image data cannot be used without reopening the image. For example: >>> from PIL import Image >>> car = Car.objects.get(name="57 Chevy") >>> car.photo.width 191 >>> car.photo.height 287 >>> image = Image.open(car.photo) # Raises ValueError: seek of closed file. >>> car.photo.open() >>> image = Image.open(car.photo) >>> image File 对象¶在内部,Django 在任何需要表示文件的时候使用 django.core.files.File 。 大部分情况下你只需要使用 Django 提供的 File (即附加到上述模型的文件或已经上传的文件)。 If you need to construct a File yourself, the easiest way is to create one using a Python built-in file object: >>> from django.core.files import File # Create a Python file object using open() >>> f = open("/path/to/hello.world", "w") >>> myfile = File(f)现在你可以使用 File 类的任何属性和方法。 Be aware that files created in this way are not automatically closed. The following approach may be used to close files automatically: >>> from django.core.files import File # Create a Python file object using open() and the with statement >>> with open("/path/to/hello.world", "w") as f: ... myfile = File(f) ... myfile.write("Hello World") ... >>> myfile.closed True >>> f.closed TrueClosing files is especially important when accessing file fields in a loop over a large number of objects. If files are not manually closed after accessing them, the risk of running out of file descriptors may arise. This may lead to the following error: OSError: [Errno 24] Too many open files 文件存储¶在后台,Django将如何以及在哪里存储文件的决策委托给文件存储系统。这个对象实际上理解文件系统、打开和读取文件等。 Django's default file storage is 'django.core.files.storage.FileSystemStorage'. If you don't explicitly provide a storage system in the default key of the STORAGES setting, this is the one that will be used. 参阅下面内置默认文件存储系统的细节,也可以查看 如何编写一个自定义的文件存储类 来了解编写自己的文件存储系统的信息。 存储对象¶Though most of the time you'll want to use a File object (which delegates to the proper storage for that file), you can use file storage systems directly. You can create an instance of some custom file storage class, or -- often more useful -- you can use the global default storage system: >>> from django.core.files.base import ContentFile >>> from django.core.files.storage import default_storage >>> path = default_storage.save("path/to/file", ContentFile(b"new content")) >>> path 'path/to/file' >>> default_storage.size(path) 11 >>> default_storage.open(path).read() b'new content' >>> default_storage.delete(path) >>> default_storage.exists(path) False查看 文件存储 API 来了解文件存储API。 内置文件存储类¶Django 附带一个 django.core.files.storage.FileSystemStorage 类,这个类实现基础的本地文件系统文件存储。 例如,下面的代码将存储上传文件到 /media/photos 而会忽略你在 MEDIA_ROOT 的设置: from django.core.files.storage import FileSystemStorage from django.db import models fs = FileSystemStorage(location="/media/photos") class Car(models.Model): ... photo = models.ImageField(storage=fs)自定义存储系统( Custom storage systems )的工作方式也一样:将它们作为 storage 参数传递给 FileField 。 使用callable¶你可以使用callable作为 FileField 或 ImageField 的 storage 参数。它允许你在运行时修改存储参数,不同环境选择不同存储,例如。 当模型类被加载时,callable将进行判断,并返回 Storage 实例。 例如: from django.conf import settings from django.db import models from .storages import MyLocalStorage, MyRemoteStorage def select_storage(): return MyLocalStorage() if settings.DEBUG else MyRemoteStorage() class MyModel(models.Model): my_file = models.FileField(storage=select_storage)In order to set a storage defined in the STORAGES setting you can use storages: from django.core.files.storage import storages def select_storage(): return storages["mystorage"] class MyModel(models.Model): upload = models.FileField(storage=select_storage) Changed in Django 4.2:Support for storages was added. |
CopyRight 2018-2019 实验室设备网 版权所有 |